package com.klm.easymq.config;

import com.klm.easymq.aspect.MQProducerAspect;
import com.klm.easymq.aspect.MQListenerAspect;
import com.klm.easymq.aspect.IdempotentAspect;
import com.klm.easymq.core.IdempotentHandler;
import com.klm.easymq.core.MessageSerializer;
import com.klm.easymq.core.MonitorService;
import com.klm.easymq.core.impl.CaffeineIdempotentHandler;
import com.klm.easymq.core.impl.JsonMessageSerializer;
import com.klm.easymq.core.impl.MemoryMonitorService;
import com.klm.easymq.core.impl.ProtobufMessageSerializer;
import com.klm.easymq.core.impl.RedisIdempotentHandler;
import com.klm.easymq.core.impl.SqliteMonitorService;
import com.klm.easymq.core.impl.EnhancedSqliteMonitorService;
import com.klm.easymq.service.EasyMqService;
import com.klm.easymq.service.impl.EasyMqServiceImpl;
import com.klm.easymq.service.MessageService;
import com.klm.easymq.service.impl.MessageServiceImpl;
import com.klm.easymq.mapper.MessageMapper;
import com.klm.easymq.client.EasyMqClient;
import com.klm.easymq.client.impl.EasyMqClientImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.Executor;

/**
 * Easy-MQ SDK 自动配置类
 * 当应用引入SDK时自动生效
 * 简化设计：只提供默认配置，环境配置由主应用管理
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(EasyMqProperties.class)
@ConditionalOnProperty(prefix = "easy-mq", name = "enabled", havingValue = "true", matchIfMissing = true)
public class EasyMqAutoConfiguration {
    
    private final ConfigurationLoader configurationLoader;
    
    public EasyMqAutoConfiguration(ConfigurationLoader configurationLoader) {
        this.configurationLoader = configurationLoader;
        initializeConfiguration();
    }
    
    /**
     * 初始化配置
     * 只加载SDK默认配置，环境配置由主应用管理
     */
    private void initializeConfiguration() {
        try {
            // 只加载SDK默认配置
            var defaultConfig = configurationLoader.loadDefaultConfig();
            
            log.info("Easy-MQ SDK 配置初始化完成，使用默认配置");
            
        } catch (Exception e) {
            log.warn("Easy-MQ SDK 配置初始化失败，将使用代码默认值: {}", e.getMessage());
        }
    }
    
    /**
     * 配置MessageService
     * 如果应用没有提供MessageService的实现，则使用默认实现
     */
    @Bean
    @ConditionalOnMissingBean
    public MessageService messageService(MessageMapper messageMapper) {
        log.info("Creating MessageService with MessageMapper");
        return new MessageServiceImpl();
    }
    
    /**
     * 配置EasyMqClient
     * 作为SDK对外提供的统一调用接口
     */
    @Bean
    @ConditionalOnMissingBean
    public EasyMqClient easyMqClient(EasyMqProperties properties,
                                   MessageService messageService,
                                   MessageSerializer messageSerializer,
                                   IdempotentHandler idempotentHandler,
                                   MonitorService monitorService,
                                   Executor asyncExecutor) {
        log.info("Creating EasyMqClient");
        return new EasyMqClientImpl(properties, messageService, messageSerializer, 
                                  idempotentHandler, monitorService, asyncExecutor);
    }
    
    /**
     * 配置Easy-MQ核心服务
     * 如果应用没有提供EasyMqService的实现，则使用默认实现
     */
    @Bean
    @ConditionalOnMissingBean
    public EasyMqService easyMqService(EasyMqProperties properties, 
                                     MessageSerializer messageSerializer,
                                     IdempotentHandler idempotentHandler,
                                     MonitorService monitorService) {
        log.info("Initializing Easy-MQ SDK with properties: {}", properties);
        return new EasyMqServiceImpl(properties, messageSerializer, idempotentHandler, monitorService);
    }
    
    /**
     * 配置AOP切面
     * 确保MQ相关的切面能够被正确加载
     */
    @Configuration
    @ConditionalOnProperty(prefix = "easy-mq", name = "enabled", havingValue = "true", matchIfMissing = true)
    static class AspectAutoConfiguration {
        
        @Bean
        @ConditionalOnMissingBean
        public MQProducerAspect mqProducerAspect() {
            return new MQProducerAspect();
        }
        
        @Bean
        @ConditionalOnMissingBean
        public MQListenerAspect mqListenerAspect() {
            return new MQListenerAspect();
        }
        
        @Bean
        @ConditionalOnMissingBean
        public IdempotentAspect idempotentAspect() {
            return new IdempotentAspect();
        }
    }
    
    /**
     * 配置RocketMQ适配器（如果存在RocketMQ配置）
     * 自动检测RocketMQ配置并启用相关功能
     */
    @Configuration
    @ConditionalOnProperty(prefix = "rocketmq", name = "name-server")
    @Import(RocketMQConfig.class)
    static class RocketMQAutoConfiguration {
        // RocketMQ相关配置会自动导入
        // 应用只需要在配置文件中设置 rocketmq.name-server 即可启用
    }
    
    /**
     * 配置幂等控制（如果启用）
     * 默认启用，应用可以通过 easy-mq.idempotent.enabled=false 禁用
     */
    @Configuration
    @ConditionalOnProperty(prefix = "easy-mq.idempotent", name = "enabled", havingValue = "true", matchIfMissing = true)
    static class IdempotentAutoConfiguration {
        // 幂等控制相关配置
        // 默认使用Caffeine本地缓存
        // 应用可以通过 easy-mq.idempotent.storage=redis 切换到Redis
    }
    
    /**
     * 配置监控功能（如果启用）
     * 默认启用，应用可以通过 easy-mq.monitor.enabled=false 禁用
     */
    @Configuration
    @ConditionalOnProperty(prefix = "easy-mq.monitor", name = "enabled", havingValue = "true", matchIfMissing = true)
    static class MonitorAutoConfiguration {
        // 监控功能相关配置
        // 默认使用SQLite存储
        // 应用可以通过 easy-mq.monitor.storage=memory 切换到内存存储
    }
    
    /**
     * 配置Web控制台（如果启用）
     */
    @Configuration
    @ConditionalOnProperty(prefix = "easy-mq.console", name = "enabled", havingValue = "true")
    @Import(WebConsoleConfig.class)
    static class WebConsoleAutoConfiguration {
        // Web控制台相关配置会自动导入
    }
    
    /**
     * 配置序列化器（如果未提供自定义实现）
     */
    @Bean
    @ConditionalOnMissingBean
    public MessageSerializer messageSerializer(EasyMqProperties properties) {
        // 根据配置创建序列化器
        if ("protobuf".equals(properties.getSerialization().getType())) {
            return new ProtobufMessageSerializer();
        } else {
            return new JsonMessageSerializer(properties.getSerialization().getJson());
        }
    }
    
    /**
     * 配置Caffeine幂等处理器（默认）
     */
    @Bean
    @ConditionalOnProperty(prefix = "easy-mq.idempotent", name = "storage", havingValue = "caffeine", matchIfMissing = true)
    @ConditionalOnMissingBean
    public IdempotentHandler caffeineIdempotentHandler(EasyMqProperties properties) {
        log.info("Creating CaffeineIdempotentHandler");
        return new CaffeineIdempotentHandler(properties.getIdempotent().getCaffeine());
    }
    
    /**
     * 配置Redis幂等处理器
     */
    @Bean
    @ConditionalOnProperty(prefix = "easy-mq.idempotent", name = "storage", havingValue = "redis")
    @ConditionalOnBean(StringRedisTemplate.class)
    @ConditionalOnMissingBean
    public IdempotentHandler redisIdempotentHandler(EasyMqProperties properties, StringRedisTemplate redisTemplate) {
        log.info("Creating RedisIdempotentHandler");
        return new RedisIdempotentHandler(properties.getIdempotent().getRedis(), redisTemplate);
    }
    
    /**
     * 配置内存监控服务
     */
    @Bean
    @ConditionalOnProperty(prefix = "easy-mq.monitor", name = "storage", havingValue = "memory")
    @ConditionalOnMissingBean
    public MonitorService memoryMonitorService() {
        log.info("Creating MemoryMonitorService");
        return new MemoryMonitorService();
    }
    
    /**
     * 配置增强版SQLite监控服务
     */
    @Bean
    @ConditionalOnProperty(prefix = "easy-mq.monitor", name = "storage", havingValue = "enhanced-sqlite")
    @ConditionalOnMissingBean
    public MonitorService enhancedSqliteMonitorService(EasyMqProperties properties) {
        log.info("Creating EnhancedSqliteMonitorService");
        return new EnhancedSqliteMonitorService(properties.getMonitor().getSqlite());
    }
    
    /**
     * 配置SQLite监控服务（默认）
     */
    @Bean
    @ConditionalOnProperty(prefix = "easy-mq.monitor", name = "storage", havingValue = "sqlite", matchIfMissing = true)
    @ConditionalOnMissingBean
    public MonitorService sqliteMonitorService(EasyMqProperties properties) {
        log.info("Creating SqliteMonitorService");
        return new SqliteMonitorService(properties.getMonitor().getSqlite());
    }
} 